import { Injectable } from '@nestjs/common';
import { CreateMenuDto } from './dto/create-menu.dto';
import { UpdateMenuDto } from './dto/update-menu.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Menu } from './entities/menu.entity';
import { responseData } from '../common/response.handle';
import { MenuItem } from './menu.interface';

@Injectable()
export class MenuService {
	constructor(
		@InjectRepository(Menu)
		private menuRepository: Repository<Menu>,
	) {}

	async create(createMenuDto: CreateMenuDto, userId: string) {
		await this.menuRepository.save(this.menuRepository.create({ ...createMenuDto, userId }));
		return responseData(null, '创建菜单成功');
	}

	async findAll() {
		const menus = await this.menuRepository
			.createQueryBuilder('menu')
			.leftJoinAndSelect('menu.userAdmin', 'user')
			.addSelect('user.email', 'creator')
			.getMany();
		const newMenus = menus.map((item) => {
			const creator = item.userAdmin.nickname;
			delete item.userAdmin;
			return {
				...item,
				creator,
			};
		}) as MenuItem[];

		// 将所有菜单项存储在一个对象中，其中键为菜单项的ID
		const menuItemsById: { [key: number]: MenuItem } = newMenus.reduce((acc, menuItem) => {
			acc[menuItem.id] = menuItem;
			return acc;
		}, {});

		// 创建一个空数组，用于存储根菜单项
		const rootMenuItems: MenuItem[] = [];

		// 将每个菜单项添加到其父级菜单项的“children”数组中
		newMenus.forEach((menuItem: MenuItem) => {
			if (menuItem.parentId === null) {
				// 如果该菜单项没有父级，则将其视为根级别菜单项
				rootMenuItems.push(menuItem);
			} else {
				// 否则，将该菜单项作为其父级的子项，并将其添加到父级菜单项的“children”数组中
				const parentMenuItem = menuItemsById[menuItem.parentId];
				if (!parentMenuItem.children) {
					parentMenuItem.children = [];
				}
				parentMenuItem.children.push(menuItem);
			}
		});

		return responseData(rootMenuItems, '查询所有菜单成功');
	}

	async findOne(id: number) {
		const menu = await this.menuRepository
			.createQueryBuilder('menu')
			.leftJoinAndSelect('menu.userAdmin', 'user')
			.addSelect('user.email', 'creator')
			.where({ id })
			.getOne();
		const newMenu = {
			...menu,
			creator: menu.userAdmin.nickname,
		};
		delete newMenu.userAdmin;
		return responseData(newMenu, '查询菜单成功');
	}

	async update(id: number, updateMenuDto: UpdateMenuDto) {
		await this.menuRepository.save(this.menuRepository.create({ ...updateMenuDto, id }));
		return responseData(null, '修改菜单成功');
	}

	async remove(id: number) {
		await this.menuRepository.delete(id);
		return responseData(null, '删除菜单成功');
	}
}
